Creating Linksets on the fly. - Improving existing code.

Hello,

I was wondering if anyone could guide me in adding additional error checking and creating linksets on the fly for restoring an archive file. For additional error checking I was think of creating an error log for mismatches between the archive module and the current module. I would also like to verify the object text, could anyone give examples. Is there anything I could do to the existing code to improve it?
Thank you,
Jim

Module m = current
Object obj
 
Module archiveModule = edit("/Requirements/Archive of Marketing Requirements", true ) 
 
void InLinks(Object hObject, Module archiveModule)
{
 // Follow the in-links from the selected object (hObject)
 
  Object     hInObj          = null
  ModName_   inModRef        = null
  LinkRef    lr              = null
  Link       in_Link         = null
  string     linkSourcePath  = null
  int        asnoCurrent     = 0
  Object     curr_obj        = null
  
  asnoCurrent = hObject."Absolute number"
  curr_obj = object(asnoCurrent, archiveModule)
  if (null curr_obj || isDeleted(curr_obj))
  {
    print "false: " asnoCurrent "\n"
  }
  else
  {
        // find the source (other end) of the in-link
        for lr in hObject <- "*" do
        {
                // get the full path to the link source
                // for in-links this is always in the other module
                linkSourcePath = fullName(source lr)
 
                // check that the returned path is valid
                if (exists(module linkSourcePath) == true)
                {
                        // check to see if the module is already open
                        if (open(module linkSourcePath) == false)
                        {
                                // open it if it is closed
                                edit(linkSourcePath, true)
                        }
                }
        }
 
        // now we know for sure those modules are open, we can do the real work
        for in_Link in hObject <- "*" do
        {
                // check the module at the other end of the link
                inModRef =  source in_Link
                if (null inModRef)      {continue}
 
                // check the object at the other end of the link
                hInObj   =  source in_Link
                if (null hInObj)        {continue}
                if (isDeleted(hInObj))  {continue} 
 
                //and finally do something useful with the source object
                hInObj->curr_obj
        }
  }
}
 
void OutLinks(Object hObject, Module archiveModule)
{
//
// This code snippet will follow the outlinks from a given object. (hObject)
//
  //Declarations
  Object    hTargetObj        = null 
  Module    targetModule      = null
  Link      outLink           = null
  int           asnoCurrent       = 0
  Object        curr_obj          = null
 
  asnoCurrent = hObject."Absolute number"
  curr_obj = object(asnoCurrent, archiveModule)
  if (null curr_obj || isDeleted(curr_obj))
  {
        print "false: " asnoCurrent "\n"
  }
  else
  {
        // now we know for sure those modules are open, we can do the real work
        for outLink in hObject -> "*" do
        {
                // full path to the module at the other end of the out_link
                string sTargetPath = fullName(target outLink)
                if (null sTargetPath) {continue}
 
                // only relevant if module exists with r access
                if (exists(module sTargetPath) == true)
                {
                        // ensure module is open
                        targetModule = read(sTargetPath, false)
                }
 
                //check that the target Module still exists
                if (null targetModule )     {continue}
 
                //check that the target object still exists
                hTargetObj = target outLink
                if (null hTargetObj)        {continue}
                if (isDeleted(hTargetObj))  {continue} 
 
                //now do something useful with the object
                curr_obj->hTargetObj
        }
  }
}
 
for obj in entire m do
{
        InLinks(obj, archiveModule)
        OutLinks(obj, archiveModule)
}

SystemAdmin - Wed Oct 19 01:03:37 EDT 2011

Re: Creating Linksets on the fly. - Improving existing code.
Mathias Mamsch - Wed Oct 19 04:28:46 EDT 2011

Some random remarks about the code:
  • When you open modules, make sure that you open it with standard view (unless you really want a default view to kick in). You can supply an additional bool parameter to the edit / read calls for that.
  • You might want to think about closing the modules you opened.
  • You should think about the link module that shall be used.
  • A general problem with link creation is errors that come from link pairing restrictions and access rights. When you create a link you should always put 'noError' .... 'lastError()' around and check the result for errors. Additionally the -> operator returns a Link, which you can check for the null value. There are a lot of error checks already in place in the linkops.inc file which ships with DOORS. I like to use a modifed
  • When you are trying to find an object by absolute number the 'object(...)' function will not always return the existing object (i.e. when the object is not visible, due to filtering, outlining, etc.). Therefore if 'object' returns null I would always double check with an 'for o in entire m do if (o."Absolute Number" == ...)' loop if the object is really not in the module or make sure you have the default view loaded and no other options applied (remember that the user could have opened the module already and have a filter applied).
  • I think the different error conditions that you ignore in the code (every 'continue' is an error condition) might be interesting for the user. Not being able to get the source or target of a link probably means that the corresponding object has been purged. Usually you do not want those links lingering around.
  • You might want to think about links to baselines. Your code is ignoring those at the moment (since you use for L in o->"*" instead of for L in all o->"*" )

As for LinkSets I am not sure where you want to go with the code? Automatically adding link pairing restrictions and linksets? Maybe the comments help a bit, regards, Mathias

Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

Re: Creating Linksets on the fly. - Improving existing code.
SystemAdmin - Wed Oct 19 10:38:37 EDT 2011

Mathias Mamsch - Wed Oct 19 04:28:46 EDT 2011
Some random remarks about the code:

  • When you open modules, make sure that you open it with standard view (unless you really want a default view to kick in). You can supply an additional bool parameter to the edit / read calls for that.
  • You might want to think about closing the modules you opened.
  • You should think about the link module that shall be used.
  • A general problem with link creation is errors that come from link pairing restrictions and access rights. When you create a link you should always put 'noError' .... 'lastError()' around and check the result for errors. Additionally the -> operator returns a Link, which you can check for the null value. There are a lot of error checks already in place in the linkops.inc file which ships with DOORS. I like to use a modifed
  • When you are trying to find an object by absolute number the 'object(...)' function will not always return the existing object (i.e. when the object is not visible, due to filtering, outlining, etc.). Therefore if 'object' returns null I would always double check with an 'for o in entire m do if (o."Absolute Number" == ...)' loop if the object is really not in the module or make sure you have the default view loaded and no other options applied (remember that the user could have opened the module already and have a filter applied).
  • I think the different error conditions that you ignore in the code (every 'continue' is an error condition) might be interesting for the user. Not being able to get the source or target of a link probably means that the corresponding object has been purged. Usually you do not want those links lingering around.
  • You might want to think about links to baselines. Your code is ignoring those at the moment (since you use for L in o->"*" instead of for L in all o->"*" )

As for LinkSets I am not sure where you want to go with the code? Automatically adding link pairing restrictions and linksets? Maybe the comments help a bit, regards, Mathias

Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

I have a questions reagrading the following:

"You might want to think about links to baselines. Your code is ignoring those at the moment (since you use for L in o->"" instead of for L in all o->"" )"

You would only be concerned about this if you were using baseline sets correct? Beacuse my understand is that all links are store in the "current" module and not in the baseline(s). Currently my project isn't using baseline sets.

Thank you,
Jim

Re: Creating Linksets on the fly. - Improving existing code.
Mathias Mamsch - Wed Oct 19 17:41:03 EDT 2011

SystemAdmin - Wed Oct 19 10:38:37 EDT 2011
I have a questions reagrading the following:

"You might want to think about links to baselines. Your code is ignoring those at the moment (since you use for L in o->"" instead of for L in all o->"" )"

You would only be concerned about this if you were using baseline sets correct? Beacuse my understand is that all links are store in the "current" module and not in the baseline(s). Currently my project isn't using baseline sets.

Thank you,
Jim

Well you are free to link to a baseline using for example "Start Link" and "Make Link From Start". A lot of customers do not use baseline sets, since one baseline cannot be part of two different sets. That is where people start moving their links around, from current to baselines and later from baselines back to current or to a different baseline. If you do not need such deeds I guess you do not need to worry about it too much. Regards, Mathias


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS